home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJINC106.ARJ / INTEGER.H < prev    next >
C/C++ Source or Header  |  1992-03-29  |  27KB  |  1,104 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2.  
  3. /* 
  4. Copyright (C) 1988 Free Software Foundation
  5.     written by Doug Lea (dl@rocky.oswego.edu)
  6.  
  7. This file is part of the GNU C++ Library.  This library is free
  8. software; you can redistribute it and/or modify it under the terms of
  9. the GNU Library General Public License as published by the Free
  10. Software Foundation; either version 2 of the License, or (at your
  11. option) any later version.  This library is distributed in the hope
  12. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  13. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  14. PURPOSE.  See the GNU Library General Public License for more details.
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #ifndef _Integer_h
  21. #ifdef __GNUG__
  22. #pragma interface
  23. #endif
  24. #define _Integer_h 1
  25.  
  26. #include <stream.h>
  27.  
  28. struct IntRep                    // internal Integer representations
  29. {
  30.   unsigned short  len;          // current length
  31.   unsigned short  sz;           // allocated space
  32.   short           sgn;          // 1 means >= 0; 0 means < 0 
  33.   unsigned short  s[1];         // represented as ushort array starting here
  34. };
  35.  
  36. extern IntRep*  Ialloc(IntRep*, const unsigned short *, int, int, int);
  37. extern IntRep*  Icalloc(IntRep*, int);
  38. extern IntRep*  Icopy_long(IntRep*, long);
  39. extern IntRep*  Icopy(IntRep*, const IntRep*);
  40. extern IntRep*  Iresize(IntRep*, int);
  41. extern IntRep*  add(const IntRep*, int, const IntRep*, int, IntRep*);
  42. extern IntRep*  add(const IntRep*, int, long, IntRep*);
  43. extern IntRep*  multiply(const IntRep*, const IntRep*, IntRep*);
  44. extern IntRep*  multiply(const IntRep*, long, IntRep*);
  45. extern IntRep*  lshift(const IntRep*, long, IntRep*);
  46. extern IntRep*  lshift(const IntRep*, const IntRep*, int, IntRep*);
  47. extern IntRep*  bitop(const IntRep*, const IntRep*, IntRep*, char);
  48. extern IntRep*  bitop(const IntRep*, long, IntRep*, char);
  49. extern IntRep*  power(const IntRep*, long, IntRep*);
  50. extern IntRep*  div(const IntRep*, const IntRep*, IntRep*);
  51. extern IntRep*  mod(const IntRep*, const IntRep*, IntRep*);
  52. extern IntRep*  div(const IntRep*, long, IntRep*);
  53. extern IntRep*  mod(const IntRep*, long, IntRep*);
  54. extern IntRep*  compl(const IntRep*, IntRep*);
  55. extern IntRep*  abs(const IntRep*, IntRep*);
  56. extern IntRep*  negate(const IntRep*, IntRep*);
  57. extern IntRep*  pow(const IntRep*, long);
  58. extern IntRep*  gcd(const IntRep*, const IntRep* y);
  59. extern int      compare(const IntRep*, const IntRep*);
  60. extern int      compare(const IntRep*, long);
  61. extern int      ucompare(const IntRep*, const IntRep*);
  62. extern int      ucompare(const IntRep*, long);
  63. extern char*    Itoa(const IntRep* x, int base = 10, int width = 0);
  64. extern char*    cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base,
  65.                         int showbase, int width, int align_right, 
  66.                         char fillchar, char Xcase, int showpos);
  67. extern IntRep*  atoIntRep(const char* s, int base = 10);
  68. extern long     Itolong(const IntRep*);
  69. extern double   Itodouble(const IntRep*);
  70. extern int      Iislong(const IntRep*);
  71. extern int      Iisdouble(const IntRep*);
  72. extern long     lg(const IntRep*);
  73.  
  74.  
  75. class Integer
  76. {
  77. protected:
  78.   IntRep*         rep;
  79. public:
  80.                   Integer();
  81.                   Integer(long);
  82.                   Integer(const Integer&);
  83.  
  84.                   ~Integer();
  85.  
  86.   void            operator =  (const Integer&);
  87.   void            operator =  (long);
  88.  
  89. // unary operations to self
  90.  
  91.   void            operator ++ ();
  92.   void            operator -- ();
  93.   void            negate();          // negate in-place
  94.   void            abs();             // absolute-value in-place
  95.   void            complement();      // bitwise complement in-place
  96.  
  97. // assignment-based operations
  98.  
  99.   void            operator += (const Integer&);
  100.   void            operator -= (const Integer&);
  101.   void            operator *= (const Integer&);
  102.   void            operator /= (const Integer&);
  103.   void            operator %= (const Integer&);
  104.   void            operator <<=(const Integer&);
  105.   void            operator >>=(const Integer&);
  106.   void            operator &= (const Integer&);
  107.   void            operator |= (const Integer&);
  108.   void            operator ^= (const Integer&);
  109.  
  110.   void            operator += (long);
  111.   void            operator -= (long);
  112.   void            operator *= (long);
  113.   void            operator /= (long);
  114.   void            operator %= (long);
  115.   void            operator <<=(long);
  116.   void            operator >>=(long);
  117.   void            operator &= (long);
  118.   void            operator |= (long);
  119.   void            operator ^= (long);
  120.  
  121. // (constructive binary operations are inlined below)
  122.  
  123. #ifdef __GNUG__
  124.   friend Integer operator <? (const Integer& x, const Integer& y); // min
  125.   friend Integer operator >? (const Integer& x, const Integer& y); // max
  126. #endif
  127.  
  128. // builtin Integer functions that must be friends
  129.  
  130.   friend long     lg (const Integer&); // floor log base 2 of abs(x)
  131.   friend double   ratio(const Integer& x, const Integer& y);
  132.                   // return x/y as a double
  133.  
  134.   friend Integer  gcd(const Integer&, const Integer&);
  135.   friend int      even(const Integer&); // true if even
  136.   friend int      odd(const Integer&); // true if odd
  137.   friend int      sign(const Integer&); // returns -1, 0, +1
  138.  
  139.   friend void     setbit(Integer& x, long b);   // set b'th bit of x
  140.   friend void     clearbit(Integer& x, long b); // clear b'th bit
  141.   friend int      testbit(const Integer& x, long b);  // return b'th bit
  142.  
  143. // procedural versions of operators
  144.  
  145.   friend void     abs(const Integer& x, Integer& dest);
  146.   friend void     negate(const Integer& x, Integer& dest);
  147.   friend void     complement(const Integer& x, Integer& dest);
  148.  
  149.   friend int      compare(const Integer&, const Integer&);  
  150.   friend int      ucompare(const Integer&, const Integer&); 
  151.   friend void     add(const Integer& x, const Integer& y, Integer& dest);
  152.   friend void     sub(const Integer& x, const Integer& y, Integer& dest);
  153.   friend void     mul(const Integer& x, const Integer& y, Integer& dest);
  154.   friend void     div(const Integer& x, const Integer& y, Integer& dest);
  155.   friend void     mod(const Integer& x, const Integer& y, Integer& dest);
  156.   friend void     divide(const Integer& x, const Integer& y, 
  157.                          Integer& q, Integer& r);
  158.   friend void     and(const Integer& x, const Integer& y, Integer& dest);
  159.   friend void     or(const Integer& x, const Integer& y, Integer& dest);
  160.   friend void     xor(const Integer& x, const Integer& y, Integer& dest);
  161.   friend void     lshift(const Integer& x, const Integer& y, Integer& dest);
  162.   friend void     rshift(const Integer& x, const Integer& y, Integer& dest);
  163.   friend void     pow(const Integer& x, const Integer& y, Integer& dest);
  164.  
  165.   friend int      compare(const Integer&, long);  
  166.   friend int      ucompare(const Integer&, long); 
  167.   friend void     add(const Integer& x, long y, Integer& dest);
  168.   friend void     sub(const Integer& x, long y, Integer& dest);
  169.   friend void     mul(const Integer& x, long y, Integer& dest);
  170.   friend void     div(const Integer& x, long y, Integer& dest);
  171.   friend void     mod(const Integer& x, long y, Integer& dest);
  172.   friend void     divide(const Integer& x, long y, Integer& q, long& r);
  173.   friend void     and(const Integer& x, long y, Integer& dest);
  174.   friend void     or(const Integer& x, long y, Integer& dest);
  175.   friend void     xor(const Integer& x, long y, Integer& dest);
  176.   friend void     lshift(const Integer& x, long y, Integer& dest);
  177.   friend void     rshift(const Integer& x, long y, Integer& dest);
  178.   friend void     pow(const Integer& x, long y, Integer& dest);
  179.  
  180.   friend int      compare(long, const Integer&);  
  181.   friend int      ucompare(long, const Integer&); 
  182.   friend void     add(long x, const Integer& y, Integer& dest);
  183.   friend void     sub(long x, const Integer& y, Integer& dest);
  184.   friend void     mul(long x, const Integer& y, Integer& dest);
  185.   friend void     and(long x, const Integer& y, Integer& dest);
  186.   friend void     or(long x, const Integer& y, Integer& dest);
  187.   friend void     xor(long x, const Integer& y, Integer& dest);
  188.  
  189. // coercion & conversion
  190.  
  191.   int             fits_in_long() const;
  192.   int             fits_in_double() const;
  193.  
  194.                   operator long() const;
  195.                   operator double() const;
  196.  
  197.   friend char*    Itoa(const Integer& x, int base = 10, int width = 0);
  198.   friend Integer  atoI(const char* s, int base = 10);
  199.   
  200.   friend istream& operator >> (istream& s, Integer& y);
  201.   friend ostream& operator << (ostream& s, const Integer& y);
  202.  
  203. // error detection
  204.  
  205.   int             initialized() const;
  206.   void   error(const char* msg) const;
  207.   int             OK() const;  
  208. };
  209.  
  210.  
  211. //  (These are declared inline)
  212.  
  213.   int      operator == (const Integer&, const Integer&);
  214.   int      operator == (const Integer&, long);
  215.   int      operator != (const Integer&, const Integer&);
  216.   int      operator != (const Integer&, long);
  217.   int      operator <  (const Integer&, const Integer&);
  218.   int      operator <  (const Integer&, long);
  219.   int      operator <= (const Integer&, const Integer&);
  220.   int      operator <= (const Integer&, long);
  221.   int      operator >  (const Integer&, const Integer&);
  222.   int      operator >  (const Integer&, long);
  223.   int      operator >= (const Integer&, const Integer&);
  224.   int      operator >= (const Integer&, long);
  225.   Integer  operator -  (const Integer&);
  226.   Integer  operator ~  (const Integer&);
  227.   Integer  operator +  (const Integer&, const Integer&);
  228.   Integer  operator +  (const Integer&, long);
  229.   Integer  operator +  (long, const Integer&);
  230.   Integer  operator -  (const Integer&, const Integer&);
  231.   Integer  operator -  (const Integer&, long);
  232.   Integer  operator -  (long, const Integer&);
  233.   Integer  operator *  (const Integer&, const Integer&);
  234.   Integer  operator *  (const Integer&, long);
  235.   Integer  operator *  (long, const Integer&);
  236.   Integer  operator /  (const Integer&, const Integer&);
  237.   Integer  operator /  (const Integer&, long);
  238.   Integer  operator %  (const Integer&, const Integer&);
  239.   Integer  operator %  (const Integer&, long);
  240.   Integer  operator << (const Integer&, const Integer&);
  241.   Integer  operator << (const Integer&, long);
  242.   Integer  operator >> (const Integer&, const Integer&);
  243.   Integer  operator >> (const Integer&, long);
  244.   Integer  operator &  (const Integer&, const Integer&);
  245.   Integer  operator &  (const Integer&, long);
  246.   Integer  operator &  (long, const Integer&);
  247.   Integer  operator |  (const Integer&, const Integer&);
  248.   Integer  operator |  (const Integer&, long);
  249.   Integer  operator |  (long, const Integer&);
  250.   Integer  operator ^  (const Integer&, const Integer&);
  251.   Integer  operator ^  (const Integer&, long);
  252.   Integer  operator ^  (long, const Integer&);
  253.  
  254.   Integer  abs(const Integer&); // absolute value
  255.   Integer  sqr(const Integer&); // square
  256.  
  257.   Integer  pow(const Integer& x, const Integer& y);
  258.   Integer  pow(const Integer& x, long y);
  259.   Integer  Ipow(long x, long y); // x to the y as Integer 
  260.  
  261.  
  262. extern char*    dec(const Integer& x, int width = 0);
  263. extern char*    oct(const Integer& x, int width = 0);
  264. extern char*    hex(const Integer& x, int width = 0);
  265. extern Integer  sqrt(const Integer&); // floor of square root
  266. extern Integer  lcm(const Integer& x, const Integer& y); // least common mult
  267.  
  268.  
  269. typedef Integer IntTmp; // for backward compatibility
  270.  
  271. inline Integer::Integer() :rep(0) {}
  272.  
  273. inline Integer::Integer(long y) :rep(Icopy_long(0, y)) {}
  274.  
  275. inline Integer::Integer(const Integer&  y) :rep(Icopy(0, y.rep)) {}
  276.  
  277. inline Integer::~Integer() { delete rep; }
  278.  
  279. inline void  Integer::operator = (const Integer&  y)
  280. {
  281.   rep = Icopy(rep, y.rep);
  282. }
  283.  
  284. inline void Integer::operator = (long y)
  285. {
  286.   rep = Icopy_long(rep, y); 
  287. }
  288.  
  289. inline Integer::operator long() const
  290.   return Itolong(rep);
  291. }
  292.  
  293. inline int Integer::initialized() const
  294. {
  295.   return rep != 0;
  296. }
  297.  
  298. inline int Integer::fits_in_long() const
  299. {
  300.   return Iislong(rep);
  301. }
  302.  
  303. inline Integer::operator double() const
  304.   return Itodouble(rep);
  305. }
  306.  
  307. inline int Integer::fits_in_double() const
  308. {
  309.   return Iisdouble(rep);
  310. }
  311.  
  312. // procedural versions
  313.  
  314. inline int compare(const Integer& x, const Integer& y)
  315. {
  316.   return compare(x.rep, y.rep);
  317. }
  318.  
  319. inline int ucompare(const Integer& x, const Integer& y)
  320. {
  321.   return ucompare(x.rep, y.rep);
  322. }
  323.  
  324. inline int compare(const Integer& x, long y)
  325. {
  326.   return compare(x.rep, y);
  327. }
  328.  
  329. inline int ucompare(const Integer& x, long y)
  330. {
  331.   return ucompare(x.rep, y);
  332. }
  333.  
  334. inline int compare(long x, const Integer& y)
  335. {
  336.   return -compare(y.rep, x);
  337. }
  338.  
  339. inline int ucompare(long x, const Integer& y)
  340. {
  341.   return -ucompare(y.rep, x);
  342. }
  343.  
  344. inline void  add(const Integer& x, const Integer& y, Integer& dest)
  345. {
  346.   dest.rep = add(x.rep, 0, y.rep, 0, dest.rep);
  347. }
  348.  
  349. inline void  sub(const Integer& x, const Integer& y, Integer& dest)
  350. {
  351.   dest.rep = add(x.rep, 0, y.rep, 1, dest.rep);
  352. }
  353.  
  354. inline void  mul(const Integer& x, const Integer& y, Integer& dest)
  355. {
  356.   dest.rep = multiply(x.rep, y.rep, dest.rep);
  357. }
  358.  
  359. inline void  div(const Integer& x, const Integer& y, Integer& dest)
  360. {
  361.   dest.rep = div(x.rep, y.rep, dest.rep);
  362. }
  363.  
  364. inline void  mod(const Integer& x, const Integer& y, Integer& dest)
  365. {
  366.   dest.rep = mod(x.rep, y.rep, dest.rep);
  367. }
  368.  
  369. inline void  and(const Integer& x, const Integer& y, Integer& dest)
  370. {
  371.   dest.rep = bitop(x.rep, y.rep, dest.rep, '&');
  372. }
  373.  
  374. inline void  or(const Integer& x, const Integer& y, Integer& dest)
  375. {
  376.   dest.rep = bitop(x.rep, y.rep, dest.rep, '|');
  377. }
  378.  
  379. inline void  xor(const Integer& x, const Integer& y, Integer& dest)
  380. {
  381.   dest.rep = bitop(x.rep, y.rep, dest.rep, '^');
  382. }
  383.  
  384. inline void  lshift(const Integer& x, const Integer& y, Integer& dest)
  385. {
  386.   dest.rep = lshift(x.rep, y.rep, 0, dest.rep);
  387. }
  388.  
  389. inline void  rshift(const Integer& x, const Integer& y, Integer& dest)
  390. {
  391.   dest.rep = lshift(x.rep, y.rep, 1, dest.rep);
  392. }
  393.  
  394. inline void  pow(const Integer& x, const Integer& y, Integer& dest)
  395. {
  396.   dest.rep = power(x.rep, long(y), dest.rep); // not incorrect
  397. }
  398.  
  399. inline void  add(const Integer& x, long y, Integer& dest)
  400. {
  401.   dest.rep = add(x.rep, 0, y, dest.rep);
  402. }
  403.  
  404. inline void  sub(const Integer& x, long y, Integer& dest)
  405. {
  406.   dest.rep = add(x.rep, 0, -y, dest.rep);
  407. }
  408.  
  409. inline void  mul(const Integer& x, long y, Integer& dest)
  410. {
  411.   dest.rep = multiply(x.rep, y, dest.rep);
  412. }
  413.  
  414. inline void  div(const Integer& x, long y, Integer& dest)
  415. {
  416.   dest.rep = div(x.rep, y, dest.rep);
  417. }
  418.  
  419. inline void  mod(const Integer& x, long y, Integer& dest)
  420. {
  421.   dest.rep = mod(x.rep, y, dest.rep);
  422. }
  423.  
  424. inline void  and(const Integer& x, long y, Integer& dest)
  425. {
  426.   dest.rep = bitop(x.rep, y, dest.rep, '&');
  427. }
  428.  
  429. inline void  or(const Integer& x, long y, Integer& dest)
  430. {
  431.   dest.rep = bitop(x.rep, y, dest.rep, '|');
  432. }
  433.  
  434. inline void  xor(const Integer& x, long y, Integer& dest)
  435. {
  436.   dest.rep = bitop(x.rep, y, dest.rep, '^');
  437. }
  438.  
  439. inline void  lshift(const Integer& x, long y, Integer& dest)
  440. {
  441.   dest.rep = lshift(x.rep, y, dest.rep);
  442. }
  443.  
  444. inline void  rshift(const Integer& x, long y, Integer& dest)
  445. {
  446.   dest.rep = lshift(x.rep, -y, dest.rep);
  447. }
  448.  
  449. inline void  pow(const Integer& x, long y, Integer& dest)
  450. {
  451.   dest.rep = power(x.rep, y, dest.rep);
  452. }
  453.  
  454. inline void abs(const Integer& x, Integer& dest)
  455. {
  456.   dest.rep = abs(x.rep, dest.rep);
  457. }
  458.  
  459. inline void negate(const Integer& x, Integer& dest)
  460. {
  461.   dest.rep = negate(x.rep, dest.rep);
  462. }
  463.  
  464. inline void complement(const Integer& x, Integer& dest)
  465. {
  466.   dest.rep = compl(x.rep, dest.rep);
  467. }
  468.  
  469. inline void  add(long x, const Integer& y, Integer& dest)
  470. {
  471.   dest.rep = add(y.rep, 0, x, dest.rep);
  472. }
  473.  
  474. inline void  sub(long x, const Integer& y, Integer& dest)
  475. {
  476.   dest.rep = add(y.rep, 1, x, dest.rep);
  477. }
  478.  
  479. inline void  mul(long x, const Integer& y, Integer& dest)
  480. {
  481.   dest.rep = multiply(y.rep, x, dest.rep);
  482. }
  483.  
  484. inline void  and(long x, const Integer& y, Integer& dest)
  485. {
  486.   dest.rep = bitop(y.rep, x, dest.rep, '&');
  487. }
  488.  
  489. inline void  or(long x, const Integer& y, Integer& dest)
  490. {
  491.   dest.rep = bitop(y.rep, x, dest.rep, '|');
  492. }
  493.  
  494. inline void  xor(long x, const Integer& y, Integer& dest)
  495. {
  496.   dest.rep = bitop(y.rep, x, dest.rep, '^');
  497. }
  498.  
  499.  
  500. // operator versions
  501.  
  502. inline int operator == (const Integer&  x, const Integer&  y)
  503. {
  504.   return compare(x, y) == 0; 
  505. }
  506.  
  507. inline int operator == (const Integer&  x, long y)
  508. {
  509.   return compare(x, y) == 0; 
  510. }
  511.  
  512. inline int operator != (const Integer&  x, const Integer&  y)
  513. {
  514.   return compare(x, y) != 0; 
  515. }
  516.  
  517. inline int operator != (const Integer&  x, long y)
  518. {
  519.   return compare(x, y) != 0; 
  520. }
  521.  
  522. inline int operator <  (const Integer&  x, const Integer&  y)
  523. {
  524.   return compare(x, y) <  0; 
  525. }
  526.  
  527. inline int operator <  (const Integer&  x, long y)
  528. {
  529.   return compare(x, y) <  0; 
  530. }
  531.  
  532. inline int operator <= (const Integer&  x, const Integer&  y)
  533. {
  534.   return compare(x, y) <= 0; 
  535. }
  536.  
  537. inline int operator <= (const Integer&  x, long y)
  538. {
  539.   return compare(x, y) <= 0; 
  540. }
  541.  
  542. inline int operator >  (const Integer&  x, const Integer&  y)
  543. {
  544.   return compare(x, y) >  0; 
  545. }
  546.  
  547. inline int operator >  (const Integer&  x, long y)
  548. {
  549.   return compare(x, y) >  0; 
  550. }
  551.  
  552. inline int operator >= (const Integer&  x, const Integer&  y)
  553. {
  554.   return compare(x, y) >= 0; 
  555. }
  556.  
  557. inline int operator >= (const Integer&  x, long y)
  558. {
  559.   return compare(x, y) >= 0; 
  560. }
  561.  
  562.  
  563. inline void  Integer::operator += (const Integer& y)
  564. {
  565.   add(*this, y, *this);
  566. }
  567.  
  568. inline void  Integer::operator += (long y)
  569. {
  570.   add(*this, y, *this);
  571. }
  572.  
  573. inline void Integer::operator ++ ()
  574. {
  575.   add(*this, 1, *this);
  576. }
  577.  
  578.  
  579. inline void  Integer::operator -= (const Integer& y)
  580. {
  581.   sub(*this, y, *this);
  582. }
  583.  
  584. inline void  Integer::operator -= (long y)
  585. {
  586.   sub(*this, y, *this);
  587. }
  588.  
  589. inline void Integer::operator -- ()
  590. {
  591.   add(*this, -1, *this);
  592. }
  593.  
  594.  
  595.  
  596. inline void Integer::operator *= (const Integer& y)
  597. {
  598.   mul(*this, y, *this);
  599. }
  600.  
  601. inline void Integer::operator *= (long y)
  602. {
  603.   mul(*this, y, *this);
  604. }
  605.  
  606.  
  607. inline void  Integer::operator &= (const Integer& y)
  608. {
  609.   and(*this, y, *this);
  610. }
  611.  
  612. inline void  Integer::operator &= (long y)
  613. {
  614.   and(*this, y, *this);
  615. }
  616.  
  617. inline void  Integer::operator |= (const Integer& y)
  618. {
  619.   or(*this, y, *this);
  620. }
  621.  
  622. inline void  Integer::operator |= (long y)
  623. {
  624.   or(*this, y, *this);
  625. }
  626.  
  627.  
  628. inline void  Integer::operator ^= (const Integer& y)
  629. {
  630.   xor(*this, y, *this);
  631. }
  632.  
  633. inline void  Integer::operator ^= (long y)
  634. {
  635.   xor(*this, y, *this);
  636. }
  637.  
  638.  
  639.  
  640. inline void Integer::operator /= (const Integer& y)
  641. {
  642.   div(*this, y, *this);
  643. }
  644.  
  645. inline void Integer::operator /= (long y)
  646. {
  647.   div(*this, y, *this);
  648. }
  649.  
  650.  
  651. inline void Integer::operator %= (const Integer& y)
  652. {
  653.   mod(*this, y, *this);
  654. }
  655.  
  656. inline void Integer::operator %= (long y)
  657. {
  658.   mod(*this, y, *this);
  659. }
  660.  
  661.  
  662. inline void Integer::operator <<= (const Integer&  y)
  663. {
  664.   lshift(*this, y, *this);
  665. }
  666.  
  667. inline void Integer::operator <<= (long  y)
  668. {
  669.   lshift(*this, y, *this);
  670. }
  671.  
  672.  
  673. inline void Integer::operator >>= (const Integer&  y)
  674. {
  675.   rshift(*this, y, *this);
  676. }
  677.  
  678. inline void  Integer::operator >>= (long y)
  679. {
  680.   rshift(*this, y, *this);
  681. }
  682.  
  683. #ifdef __GNUG__
  684. inline Integer operator <? (const Integer& x, const Integer& y)
  685. {
  686.   return (compare(x.rep, y.rep) <= 0) ? x : y;
  687. }
  688.  
  689. inline Integer operator >? (const Integer& x, const Integer& y)
  690. {
  691.   return (compare(x.rep, y.rep) >= 0)?  x : y;
  692. }
  693. #endif
  694.  
  695.  
  696. inline void Integer::abs()
  697. {
  698.   ::abs(*this, *this);
  699. }
  700.  
  701. inline void Integer::negate()
  702. {
  703.   ::negate(*this, *this);
  704. }
  705.  
  706.  
  707. inline void Integer::complement()
  708. {
  709.   ::complement(*this, *this);
  710. }
  711.  
  712.  
  713. inline int sign(const Integer& x)
  714. {
  715.   return (x.rep->len == 0) ? 0 : ( (x.rep->sgn == 1) ? 1 : -1 );
  716. }
  717.  
  718. inline int even(const Integer& y)
  719. {
  720.   return y.rep->len == 0 || !(y.rep->s[0] & 1);
  721. }
  722.  
  723. inline int odd(const Integer& y)
  724. {
  725.   return y.rep->len > 0 && (y.rep->s[0] & 1);
  726. }
  727.  
  728. inline char* Itoa(const Integer& y, int base, int width)
  729. {
  730.   return Itoa(y.rep, base, width);
  731. }
  732.  
  733.  
  734.  
  735. inline long lg(const Integer& x) 
  736. {
  737.   return lg(x.rep);
  738. }
  739.  
  740. // constructive operations 
  741.  
  742. #if defined(__GNUG__) && !defined(NO_NRV)
  743.  
  744. inline Integer  operator +  (const Integer& x, const Integer& y) return r
  745. {
  746.   add(x, y, r);
  747. }
  748.  
  749. inline Integer  operator +  (const Integer& x, long y) return r
  750. {
  751.   add(x, y, r);
  752. }
  753.  
  754. inline Integer  operator +  (long  x, const Integer& y) return r
  755. {
  756.   add(x, y, r);
  757. }
  758.  
  759. inline Integer  operator -  (const Integer& x, const Integer& y) return r
  760. {
  761.   sub(x, y, r);
  762. }
  763.  
  764. inline Integer  operator -  (const Integer& x, long y) return r
  765. {
  766.   sub(x, y, r);
  767. }
  768.  
  769. inline Integer  operator -  (long  x, const Integer& y) return r
  770. {
  771.   sub(x, y, r);
  772. }
  773.  
  774. inline Integer  operator *  (const Integer& x, const Integer& y) return r
  775. {
  776.   mul(x, y, r);
  777. }
  778.  
  779. inline Integer  operator *  (const Integer& x, long y) return r
  780. {
  781.   mul(x, y, r);
  782. }
  783.  
  784. inline Integer  operator *  (long  x, const Integer& y) return r
  785. {
  786.   mul(x, y, r);
  787. }
  788.  
  789. inline Integer sqr(const Integer& x) return r
  790. {
  791.   mul(x, x, r);
  792. }
  793.  
  794. inline Integer  operator &  (const Integer& x, const Integer& y) return r
  795. {
  796.   and(x, y, r);
  797. }
  798.  
  799. inline Integer  operator &  (const Integer& x, long y) return r
  800. {
  801.   and(x, y, r);
  802. }
  803.  
  804. inline Integer  operator &  (long  x, const Integer& y) return r
  805. {
  806.   and(x, y, r);
  807. }
  808.  
  809. inline Integer  operator |  (const Integer& x, const Integer& y) return r
  810. {
  811.   or(x, y, r);
  812. }
  813.  
  814. inline Integer  operator |  (const Integer& x, long y) return r
  815. {
  816.   or(x, y, r);
  817. }
  818.  
  819. inline Integer  operator |  (long  x, const Integer& y) return r
  820. {
  821.   or(x, y, r);
  822. }
  823.  
  824. inline Integer  operator ^  (const Integer& x, const Integer& y) return r
  825. {
  826.   xor(x, y, r);
  827. }
  828.  
  829. inline Integer  operator ^  (const Integer& x, long y) return r
  830. {
  831.   xor(x, y, r);
  832. }
  833.  
  834. inline Integer  operator ^  (long  x, const Integer& y) return r
  835. {
  836.   xor(x, y, r);
  837. }
  838.  
  839. inline Integer  operator /  (const Integer& x, const Integer& y) return r
  840. {
  841.   div(x, y, r);
  842. }
  843.  
  844. inline Integer operator /  (const Integer& x, long y) return r
  845. {
  846.   div(x, y, r);
  847. }
  848.  
  849. inline Integer operator %  (const Integer& x, const Integer& y) return r
  850. {
  851.   mod(x, y, r);
  852. }
  853.  
  854. inline Integer operator %  (const Integer& x, long y) return r
  855. {
  856.   mod(x, y, r);
  857. }
  858.  
  859. inline Integer operator <<  (const Integer& x, const Integer& y) return r
  860. {
  861.   lshift(x, y, r);
  862. }
  863.  
  864. inline Integer operator <<  (const Integer& x, long y) return r
  865. {
  866.   lshift(x, y, r);
  867. }
  868.  
  869. inline Integer operator >>  (const Integer& x, const Integer& y) return r;
  870. {
  871.   rshift(x, y, r);
  872. }
  873.  
  874. inline Integer operator >>  (const Integer& x, long y) return r
  875. {
  876.   rshift(x, y, r);
  877. }
  878.  
  879. inline Integer pow(const Integer& x, long y) return r
  880. {
  881.   pow(x, y, r);
  882. }
  883.  
  884. inline Integer Ipow(long x, long y) return r(x)
  885. {
  886.   pow(r, y, r);
  887. }
  888.  
  889. inline Integer pow(const Integer& x, const Integer& y) return r
  890. {
  891.   pow(x, y, r);
  892. }
  893.  
  894.  
  895.  
  896. inline Integer abs(const Integer& x) return r
  897. {
  898.   abs(x, r);
  899. }
  900.  
  901. inline Integer operator - (const Integer& x) return r
  902. {
  903.   negate(x, r);
  904. }
  905.  
  906. inline Integer operator ~ (const Integer& x) return r
  907. {
  908.   complement(x, r);
  909. }
  910.  
  911. inline Integer  atoI(const char* s, int base) return r
  912. {
  913.   r.rep = atoIntRep(s, base);
  914. }
  915.  
  916. inline Integer  gcd(const Integer& x, const Integer& y) return r
  917. {
  918.   r.rep = gcd(x.rep, y.rep);
  919. }
  920.  
  921. #else /* NO_NRV */
  922.  
  923. inline Integer  operator +  (const Integer& x, const Integer& y) 
  924. {
  925.   Integer r; add(x, y, r); return r;
  926. }
  927.  
  928. inline Integer  operator +  (const Integer& x, long y) 
  929. {
  930.   Integer r; add(x, y, r); return r;
  931. }
  932.  
  933. inline Integer  operator +  (long  x, const Integer& y) 
  934. {
  935.   Integer r; add(x, y, r); return r;
  936. }
  937.  
  938. inline Integer  operator -  (const Integer& x, const Integer& y) 
  939. {
  940.   Integer r; sub(x, y, r); return r;
  941. }
  942.  
  943. inline Integer  operator -  (const Integer& x, long y) 
  944. {
  945.   Integer r; sub(x, y, r); return r;
  946. }
  947.  
  948. inline Integer  operator -  (long  x, const Integer& y) 
  949. {
  950.   Integer r; sub(x, y, r); return r;
  951. }
  952.  
  953. inline Integer  operator *  (const Integer& x, const Integer& y) 
  954. {
  955.   Integer r; mul(x, y, r); return r;
  956. }
  957.  
  958. inline Integer  operator *  (const Integer& x, long y) 
  959. {
  960.   Integer r; mul(x, y, r); return r;
  961. }
  962.  
  963. inline Integer  operator *  (long  x, const Integer& y) 
  964. {
  965.   Integer r; mul(x, y, r); return r;
  966. }
  967.  
  968. inline Integer sqr(const Integer& x) 
  969. {
  970.   Integer r; mul(x, x, r); return r;
  971. }
  972.  
  973. inline Integer  operator &  (const Integer& x, const Integer& y) 
  974. {
  975.   Integer r; and(x, y, r); return r;
  976. }
  977.  
  978. inline Integer  operator &  (const Integer& x, long y) 
  979. {
  980.   Integer r; and(x, y, r); return r;
  981. }
  982.  
  983. inline Integer  operator &  (long  x, const Integer& y) 
  984. {
  985.   Integer r; and(x, y, r); return r;
  986. }
  987.  
  988. inline Integer  operator |  (const Integer& x, const Integer& y) 
  989. {
  990.   Integer r; or(x, y, r); return r;
  991. }
  992.  
  993. inline Integer  operator |  (const Integer& x, long y) 
  994. {
  995.   Integer r; or(x, y, r); return r;
  996. }
  997.  
  998. inline Integer  operator |  (long  x, const Integer& y) 
  999. {
  1000.   Integer r; or(x, y, r); return r;
  1001. }
  1002.  
  1003. inline Integer  operator ^  (const Integer& x, const Integer& y) 
  1004. {
  1005.   Integer r; xor(x, y, r); return r;
  1006. }
  1007.  
  1008. inline Integer  operator ^  (const Integer& x, long y) 
  1009. {
  1010.   Integer r; xor(x, y, r); return r;
  1011. }
  1012.  
  1013. inline Integer  operator ^  (long  x, const Integer& y) 
  1014. {
  1015.   Integer r; xor(x, y, r); return r;
  1016. }
  1017.  
  1018. inline Integer  operator /  (const Integer& x, const Integer& y) 
  1019. {
  1020.   Integer r; div(x, y, r); return r;
  1021. }
  1022.  
  1023. inline Integer operator /  (const Integer& x, long y) 
  1024. {
  1025.   Integer r; div(x, y, r); return r;
  1026. }
  1027.  
  1028. inline Integer operator %  (const Integer& x, const Integer& y) 
  1029. {
  1030.   Integer r; mod(x, y, r); return r;
  1031. }
  1032.  
  1033. inline Integer operator %  (const Integer& x, long y) 
  1034. {
  1035.   Integer r; mod(x, y, r); return r;
  1036. }
  1037.  
  1038. inline Integer operator <<  (const Integer& x, const Integer& y) 
  1039. {
  1040.   Integer r; lshift(x, y, r); return r;
  1041. }
  1042.  
  1043. inline Integer operator <<  (const Integer& x, long y) 
  1044. {
  1045.   Integer r; lshift(x, y, r); return r;
  1046. }
  1047.  
  1048. inline Integer operator >>  (const Integer& x, const Integer& y) 
  1049. {
  1050.   Integer r; rshift(x, y, r); return r;
  1051. }
  1052.  
  1053. inline Integer operator >>  (const Integer& x, long y) 
  1054. {
  1055.   Integer r; rshift(x, y, r); return r;
  1056. }
  1057.  
  1058. inline Integer pow(const Integer& x, long y) 
  1059. {
  1060.   Integer r; pow(x, y, r); return r;
  1061. }
  1062.  
  1063. inline Integer Ipow(long x, long y) 
  1064. {
  1065.   Integer r(x); pow(r, y, r); return r;
  1066. }
  1067.  
  1068. inline Integer pow(const Integer& x, const Integer& y) 
  1069. {
  1070.   Integer r; pow(x, y, r); return r;
  1071. }
  1072.  
  1073.  
  1074.  
  1075. inline Integer abs(const Integer& x) 
  1076. {
  1077.   Integer r; abs(x, r); return r;
  1078. }
  1079.  
  1080. inline Integer operator - (const Integer& x) 
  1081. {
  1082.   Integer r; negate(x, r); return r;
  1083. }
  1084.  
  1085. inline Integer operator ~ (const Integer& x) 
  1086. {
  1087.   Integer r; complement(x, r); return r;
  1088. }
  1089.  
  1090. inline Integer  atoI(const char* s, int base) 
  1091. {
  1092.   Integer r; r.rep = atoIntRep(s, base); return r;
  1093. }
  1094.  
  1095. inline Integer  gcd(const Integer& x, const Integer& y) 
  1096. {
  1097.   Integer r; r.rep = gcd(x.rep, y.rep); return r;
  1098. }
  1099.  
  1100. #endif  /* NO_NRV */
  1101. #endif /* !_Integer_h */
  1102.